/*
 * ClientGUIView.java
 */

package bankingSystemClient;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Vector;

import javax.swing.*;

import bankingSystemServer.AccountInfo;

import communicationClasses.TransactionReply;
import communicationClasses.TransactionRequest;
import communicationClasses.TransferRequest;
import communicationClasses.TransactionRequest.TransactionType;

/**
 * A Client GUI for the online banking system
 * 
 * @author Jason Brown
 */
public class ClientGUIView extends JFrame {

	/**
	 * Generated Serial Version ID
	 */
	private static final long serialVersionUID = 7219545647354528028L;
	public static final int DEPOSIT = 0;
	public static final int WITHDRAWL = 1;
	public static final int TRANSFER = 2;
	public static final int ACCOUNT_HISTORY = 3;

	// Variables declaration
	private JLabel ActionjLabel;
	private JLabel AmountjLabel;
	private JTextField AmountjTextField;
	private JLabel FillSpacejLabel;
	private JLabel FromAccountjLabel;
	private JTextField FromAccountjTextField;
	private JMenu fileMenu, helpMenu;
	private JMenuItem exitMenuItem, aboutMenuItem;
	private JMenuItem LoginMenuItem;
	private JMenuItem AdminLoginMenuItem;
	private JMenu LogonMenu;
	private JMenuItem LogoutMenuItem;
	private JButton SubmitjButton;
	private JLabel ToAccountjLabel;
	private JTextField ToAccountjTextField;
	private JComboBox transactionComboBox;
	private JComboBox fromComboBox;
	private JComboBox toComboBox;
	private JScrollPane jScrollPane1;
	private JTextArea jTextArea;
	private JMenuBar menuBar;
	private JPanel mainPanel;
	private JPanel statusPanel;
	private BorderLayout borderlayout;
	private ClientModel cm;
	private JDialog aboutBox;
	private Socket socket;
	private ObjectOutputStream objectOutputStream;
	private ObjectInputStream objectInputStream;
	private LoginBox loginBox;
	private AccountInfo accountInfo;
	private Vector<AccountInfo> accounts;
	private JMenuItem jmi;

	/**
	 * Constructor which calls initComponents to initialize the form
	 */
	public ClientGUIView() {
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}
		initComponents();
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 */

	private void initComponents() {

		mainPanel = new JPanel();
		jScrollPane1 = new JScrollPane();
		jTextArea = new JTextArea();
		jTextArea.setText("You must first logon to begin.\n\nSelect Logon and then Login from the menu.");
		menuBar = new JMenuBar();
		fileMenu = new JMenu("File");
		exitMenuItem = new JMenuItem("Exit");
		LogonMenu = new JMenu("Logon");
		LoginMenuItem = new JMenuItem("Login");
		AdminLoginMenuItem = new JMenuItem("Admin Login");
		AdminLoginMenuItem.addActionListener(new MenuListener());
		LoginMenuItem.addActionListener(new MenuListener());
		LogoutMenuItem = new JMenuItem("Logoff");
		LogoutMenuItem.addActionListener(new MenuListener());
		helpMenu = new JMenu("Help");
		aboutMenuItem = new JMenuItem("About");
		statusPanel = new JPanel();
		AmountjLabel = new JLabel("Amount");
		AmountjTextField = new JTextField();
		ActionjLabel = new JLabel("Transaction Type");
		transactionComboBox = new JComboBox();
		fromComboBox = new JComboBox();
		toComboBox = new JComboBox();
		FromAccountjLabel = new JLabel("From Account");
		FromAccountjTextField = new JTextField();
		ToAccountjLabel = new JLabel("To Account");
		ToAccountjTextField = new JTextField();
		FillSpacejLabel = new JLabel();
		SubmitjButton = new JButton("Submit");
		SubmitjButton.addActionListener(new SubmitListener());
		borderlayout = new BorderLayout();
		cm = new ClientModel();
		cm.disableControls();

		// Setting the frame parameters
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setSize(400, 600);
		this.setTitle("Client");
		this.setResizable(false);

		// Setting properties for the main jTextArea
		jTextArea.setColumns(20);
		jTextArea.setEditable(false);
		jTextArea.setRows(8);
		jScrollPane1.setViewportView(jTextArea);

		// Assigning default values to the jComboBoxes
		transactionComboBox.setModel(new javax.swing.DefaultComboBoxModel(
				new String[] { "Deposit", "Withdrawal", "Transfer",
						"Get Account History" }));
		/*
		fromComboBox.setModel(new javax.swing.DefaultComboBoxModel(
				new String[] { "Account number 1", "Account number 2" }));
		toComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] {
				"Account number 1", "Account number 2" }));
				*/
		fromComboBox = new JComboBox();
		toComboBox = new JComboBox();

		// Creating the menus
		fileMenu.add(exitMenuItem);
		LogonMenu.add(LoginMenuItem);
		LogonMenu.add(AdminLoginMenuItem);
		LogonMenu.add(LogoutMenuItem);
		helpMenu.add(aboutMenuItem);
		menuBar.add(fileMenu);
		menuBar.add(LogonMenu);
		menuBar.add(helpMenu);

		// Creating the status panel
		statusPanel.setName("statusPanel");
		statusPanel.setPreferredSize(new java.awt.Dimension(400, 150));
		statusPanel.setLayout(new java.awt.GridLayout(5, 2, 1, 1));
		statusPanel.add(AmountjLabel);
		statusPanel.add(AmountjTextField);
		statusPanel.add(ActionjLabel);
		statusPanel.add(transactionComboBox);
		statusPanel.add(FromAccountjLabel);
		statusPanel.add(fromComboBox);
		statusPanel.add(ToAccountjLabel);
		statusPanel.add(toComboBox);
		statusPanel.add(FillSpacejLabel);
		statusPanel.add(SubmitjButton);

		// Set the layout and add components to the main panel
		mainPanel.setLayout(borderlayout);
		mainPanel.add(menuBar, BorderLayout.NORTH);
		mainPanel.add(jScrollPane1, BorderLayout.CENTER);
		mainPanel.add(statusPanel, borderlayout.SOUTH);

		// Add the mainPanel to this jFrame and make it visible
		this.add(mainPanel);
		this.setVisible(true);
		this.setLocationRelativeTo(null);
	}

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[]) {
		ClientGUIView cgv = new ClientGUIView();

	}

	private class SubmitListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			cm.amount = Integer.parseInt(AmountjTextField.getText());
			cm.fromAcc = FromAccountjTextField.getText();
			cm.toAcc = ToAccountjTextField.getText();
			// TODO handle cases properly
			try {
				//Make deposit case
				if (transactionComboBox.getSelectedIndex() == DEPOSIT) {
					AccountInfo ai = (AccountInfo) toComboBox.getSelectedItem();
					objectOutputStream.writeObject(new TransactionRequest(ai.getAccountNumber(),
							TransactionType.DEPOSIT, cm.amount));
					/*
					Object accountsInfo = objectInputStream.readObject();
					if (accountsInfo instanceof Vector<?>) {
						accounts = (Vector<AccountInfo>) accountsInfo;
					}*/
					Object replyObject = objectInputStream.readObject();
					if(replyObject instanceof TransactionReply){
						TransactionReply reply = (TransactionReply)replyObject;
					}
					
				//Make withdrawl case
				} else if (transactionComboBox.getSelectedIndex() == WITHDRAWL) {
					AccountInfo ai = (AccountInfo) fromComboBox.getSelectedItem();
					objectOutputStream.writeObject(new TransactionRequest(ai.getAccountNumber(),
							TransactionType.DEPOSIT, cm.amount));
					Object accountsInfo = objectInputStream.readObject();
					if (accountsInfo instanceof Vector<?>) {
						accounts = (Vector<AccountInfo>) accountsInfo;
					}
					
				/* Transfer funds case
				 * 
				 * create transfer request(customer, acc1, acc2, amount)
				 * write to stream
				 * 
				 * 
				 */
				} else if (transactionComboBox.getSelectedIndex() == TRANSFER) {
					objectOutputStream.writeObject(new TransferRequest(cm.customer,
							cm.fromAcc, cm.toAcc, cm.amount));
					
				//Get account history
				} else if (transactionComboBox.getSelectedIndex() == ACCOUNT_HISTORY) {
					// System.out.println("You choose Account History");
				}
			} catch (IOException e1) {
				e1.printStackTrace();
			} catch (ClassNotFoundException e2) {
				e2.printStackTrace();
			}

			jTextArea.setText("You clicked submit");
			jTextArea.append("\nOption selected " + transactionComboBox.getSelectedIndex());

		}
	}

	private class MenuListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			if (e.getSource() instanceof JMenuItem) {
				jmi = (JMenuItem) e.getSource();
			}
			if (jmi.getText().equalsIgnoreCase("Login")) {
				loginBox = new LoginBox(cm, socket, objectOutputStream,
					objectInputStream, accounts);
				loginBox.setVisible(true);
			}
			if (jmi.getText().equalsIgnoreCase("Admin Login")) {
				loginBox = new LoginBox(cm, socket, objectOutputStream,
						objectInputStream, accounts);
				loginBox.setVisible(true);
				}
			if (jmi.getText().equalsIgnoreCase("Logoff")) {
				try {
					objectInputStream.close();
					objectOutputStream.close();
					socket.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	protected class ClientModel {
		int amount;
		String toAcc, fromAcc, transactionType, customer;

		public ClientModel() {
			fromAcc = "";
			toAcc = "";
			amount = 0;
			transactionType = "";
			customer = "";
		}

		public void updateGUIFields() {
			// TODO update all fields after a successful login
			// jTextArea.setText(accountInfo.toString());
			for (AccountInfo accountInfo : accounts) {
				fromComboBox.addItem(accountInfo);
				toComboBox.addItem(accountInfo);
			}

		}

		public void setAccounts() {
			accounts = loginBox.getAccounts();
		}
		public void getSocket() {
			socket = loginBox.getSocket();
		}

		public void enableControls() {
			AmountjTextField.setEnabled(true);
			transactionComboBox.setEnabled(true);
			fromComboBox.setEnabled(true);
			toComboBox.setEnabled(true);
			SubmitjButton.setEnabled(true);
		}

		public void disableControls() {
			AmountjTextField.setEnabled(false);
			transactionComboBox.setEnabled(false);
			fromComboBox.setEnabled(false);
			toComboBox.setEnabled(false);
			SubmitjButton.setEnabled(false);
		}

		public void writeToTextArea(String msg) {
			jTextArea.setText(msg);
		}

	}
}
